#include <iostream>
#include <vector>
#include <string>
using namespace std;

string longestCommonSubstring(const string& s1, const string& s2) {
    int m = s1.length();
    int n = s2.length();
    
    if (m == 0 || n == 0) {
        return "";
    }
    
    // 创建动态规划表
    vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
    int maxLength = 0;  // 记录最长公共子字符串的长度
    int endIndex = 0;   // 记录最长公共子字符串在s1中的结束位置
    
    // 填充动态规划表
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s1[i - 1] == s2[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                if (dp[i][j] > maxLength) {
                    maxLength = dp[i][j];
                    endIndex = i - 1; // 记录结束位置
                }
            } else {
                dp[i][j] = 0;
            }
        }
    }
    
    // 提取最长公共子字符串
    if (maxLength == 0) {
        return "";
    }
    
    return s1.substr(endIndex - maxLength + 1, maxLength);
}